home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / fn-cache.cc < prev    next >
C/C++ Source or Header  |  1996-11-09  |  6KB  |  252 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26.  
  27. #include <string>
  28.  
  29. #include "file-ops.h"
  30. #include "str-vec.h"
  31.  
  32. #include <defaults.h>
  33. #include "dir-ops.h"
  34. #include "dirfns.h"
  35. #include "error.h"
  36. #include "fn-cache.h"
  37. #include "pathsearch.h"
  38.  
  39. octave_fcn_file_name_cache *octave_fcn_file_name_cache::instance = 0;
  40.  
  41. // Update the cache.  Returns TRUE if something needed to be updated.
  42.  
  43. // We just accumulate all directories ever referenced in the cache and
  44. // we don't delete any old ones.
  45.  
  46. bool
  47. octave_fcn_file_name_cache::update (const string& path)
  48. {
  49.   bool something_changed = false;
  50.  
  51.   dir_path p = path.empty () ? dir_path (Vload_path) : dir_path (path);
  52.  
  53.   string_vector dirs = p.all_directories ();
  54.  
  55.   int len = dirs.length ();
  56.  
  57.   for (int i = 0; i < len; i++)
  58.     {
  59.       string d = dirs[i];
  60.  
  61.       if (cache.contains (d))
  62.     {
  63.       if (cache[d].update (d))
  64.         something_changed = true;
  65.     }
  66.       else
  67.     {
  68.       cache[d] = file_name_cache_elt (d);
  69.       something_changed = true;
  70.     }
  71.     }
  72.  
  73.   return something_changed;
  74. }
  75.  
  76. string_vector
  77. octave_fcn_file_name_cache::list (const string& path, bool no_suffix)
  78. {
  79.   string_vector retval;
  80.  
  81.   if (! instance)
  82.     instance = new octave_fcn_file_name_cache ();
  83.  
  84.   if (instance)
  85.     retval = instance->do_list (path, no_suffix);
  86.   else
  87.     panic_impossible ();
  88.  
  89.   return retval;
  90. }
  91.  
  92. // Check to see if any of the elements in the cache need to be
  93. // updated, then return the list of names in the cache.
  94.  
  95. string_vector
  96. octave_fcn_file_name_cache::do_list (const string& path, bool no_suffix)
  97. {
  98.   update (path);
  99.  
  100.   string_vector fcn_file_names;
  101.   string_vector fcn_file_names_no_suffix;
  102.  
  103.   // For now, always generate the list of function files on each
  104.   // call.
  105.  
  106.   // XXX FIXME XXX -- this could probably be improved by keeping lists
  107.   // of all the function files for the current load path and only
  108.   // updating that when the load path changes.  Have to be careful to
  109.   // return the right thing when we are only looking for a subset of
  110.   // all the files in the load path.
  111.  
  112.   int total_len = 0;
  113.  
  114.   dir_path p = path.empty () ? dir_path (Vload_path) : dir_path (path);
  115.  
  116.   string_vector dirs = p.all_directories ();
  117.  
  118.   int ndirs = dirs.length ();
  119.  
  120.   if (ndirs > 1)
  121.     {
  122.       for (int i = 0; i < ndirs; i++)
  123.     {
  124.       string d = dirs[i];
  125.  
  126.       total_len += cache[d].length ();
  127.     }
  128.  
  129.       fcn_file_names.resize (total_len);
  130.       fcn_file_names_no_suffix.resize (total_len);
  131.  
  132.       int k = 0;
  133.  
  134.       for (int j = 0; j < ndirs; j++)
  135.     {
  136.       string d = dirs[j];
  137.  
  138.       file_name_cache_elt elt = cache[d];
  139.  
  140.       int len = elt.length ();
  141.  
  142.       string_vector ffn = elt.fcn_file_names;
  143.       string_vector ffnns = elt.fcn_file_names_no_suffix;
  144.  
  145.       for (int i = 0; i < len; i++)
  146.         {
  147.           fcn_file_names[k] = ffn[i];
  148.           fcn_file_names_no_suffix[k] = ffnns[i];
  149.  
  150.           k++;
  151.         }
  152.     }
  153.     }
  154.   else if (ndirs == 1)
  155.     {
  156.       string d = dirs[0];
  157.  
  158.       file_name_cache_elt elt = cache[d];
  159.  
  160.       fcn_file_names = elt.fcn_file_names;
  161.       fcn_file_names_no_suffix = elt.fcn_file_names_no_suffix;
  162.     }
  163.  
  164.   return no_suffix ? fcn_file_names_no_suffix : fcn_file_names;
  165. }
  166.  
  167. // Create a list of the function names in a given directory.  Returns
  168. // TRUE if the cache element was out of date.
  169.  
  170. bool
  171. file_name_cache_elt::update (const string& dir_name)
  172. {
  173.   bool retval = false;
  174.  
  175.   file_stat file (dir_name);
  176.  
  177.   // If the directory doesn't exist, delete the names in the cache.
  178.   // If it does exist,read it only if it is out of date.
  179.  
  180.   if (file)
  181.     {
  182.       if (file.is_newer (timestamp))
  183.     {
  184.       retval = true;
  185.  
  186.       timestamp = file.mtime ();
  187.  
  188.       dir_entry dir (dir_name);
  189.  
  190.       if (dir)
  191.         {
  192.           string_vector tmp = dir.read ();
  193.  
  194.           int max_len = tmp.length ();
  195.  
  196.           fcn_file_names.resize (max_len);
  197.           fcn_file_names_no_suffix.resize (max_len);
  198.  
  199.           int k = 0;
  200.           int i;
  201.           for (i = 0; i < max_len; i++)
  202.         {
  203.           string entry = tmp[i];
  204.  
  205.           int len = entry.length ();
  206.  
  207. #if defined (WITH_DYNAMIC_LINKING)
  208.           if ((len > 2
  209.                && entry[len-2] == '.' && entry[len-1] == 'm')
  210.               || (len > 4
  211.               && entry[len-4] == '.' && entry[len-3] == 'o'
  212.               && entry[len-2] == 'c' && entry[len-1] == 't'))
  213. #else
  214.           if (len > 2
  215.               && entry[len-2] == '.' && entry[len-1] == 'm')
  216. #endif
  217.             {
  218.               fcn_file_names[k] = entry;
  219.  
  220.               fcn_file_names_no_suffix[k] = (entry[len-1] == 'm')
  221.             ? string (entry, 0, len-2)
  222.             : string (entry, 0, len-4);
  223.  
  224.               k++;
  225.             }
  226.         }
  227.  
  228.           fcn_file_names.resize (k);
  229.           fcn_file_names_no_suffix.resize (k);
  230.         }
  231.       else
  232.         {
  233.           fcn_file_names.resize (0);
  234.           fcn_file_names_no_suffix.resize (0);
  235.         }
  236.     }
  237.     }
  238.   else
  239.     {
  240.       fcn_file_names.resize (0);
  241.       fcn_file_names_no_suffix.resize (0);
  242.     }
  243.  
  244.   return retval;
  245. }
  246.  
  247. /*
  248. ;;; Local Variables: ***
  249. ;;; mode: C++ ***
  250. ;;; End: ***
  251. */
  252.